
/****************************************************************************
**
** Copyright (C) 2004-2008 VATATA.com . All rights reserved.
**
** This file is the part of the Miniutil Poject.
** Vatata's miniutil library is lightweight and portable (for linux
** and Windows). The C++ Class Library included Threadpool, Dll danymic loading, 
** General socket application model and tcp server, httpserver/servlet, etc. 
** It is a pratical utility disigned for who don't want learn the Big C++ 
** Developing Platform, such as  Boost or ACE.
**
** This file may be used under the terms of the GNU General Public
** License versions 2.0 or 3.0 as published by the Free Software
** Foundation and appearing in the files LICENSE.GPL2 and LICENSE.GPL3
** included in the packaging of this file.  Alternatively you may (at
** your option) use any later version of the GNU General Public
** License if such license has been publicly approved by VATATA.com.
** (or its successors, if any) and the Miniutil Project Aministrators. 
**
** Please review the following information to ensure GNU General
** Public Licensing requirements will be met:
** http://www.gnu.org/licenses/lgpl.html. If you are unsure which 
** license is appropriate for your use, please review the following 
** information: http://code.google.com/p/miniutil/ or contact 
** http://www.vatata.com.
**
** In addition, as a special exception, VATATA.com, as the sole
** copyright holder for Miniutil Project, grants users of VATATA
** P2P Platform the right to release and package with the related 
** libraries without the source code.
**
** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
** A PARTICULAR PURPOSE. vatata reserves all rights not expressly
** granted herein.
**
** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
**
****************************************************************************/


#ifndef __MINIUTIL_DATA_ALLOC_H__
#define __MINIUTIL_DATA_ALLOC_H__

#include <vector>
#include <map>
#include <set>
#include "miniutil/thread.h"

namespace miniutil
{
	namespace data
	{
		class buffer_alloc
		{
		public:
			buffer_alloc();
			virtual ~buffer_alloc();
		public:
			char* retrieve_mem(unsigned int len);
			int release_mem(char*, unsigned int len= 0);
		public:
			bool wouldoverflow(); //return true if the total_system_allocate have larger than the value setting
			int setoverflowthreshold(int);

			int get_current_size();
			int get_retrieve_num();
			int get_release_num();
			int get_system_allocate();
			virtual std::string dump_stus(int level = 0);
		protected:
			virtual char* malloc_mem(unsigned int &len);
			virtual int free_mem(char*, unsigned int len);
		protected:
			std::map<char*, std::pair<unsigned int, unsigned int> >memalloc; //memory pointer, (invoker want size, actual allocate size)
			miniutil::mutex allocmtx;
			unsigned int retrieve_num;
			unsigned int release_num;
			unsigned int total_allocate_size;
			unsigned int total_free_size;
			unsigned int total_system_allocate;

			int mofthreshold;
		};

		class pool_buffer_alloc:public buffer_alloc
		{
		public:
			static pool_buffer_alloc* getdefaultinstance();
		private:
			static pool_buffer_alloc* pinstance;
		public:
			pool_buffer_alloc();
			virtual ~pool_buffer_alloc();
			int pre_alloc(unsigned int size, unsigned int count);
			virtual std::string dump_stus(int level = 0);
			int set_poolcachethreshold(int num){mmaxcachesize = num;return 0;}
		protected:
			virtual char* malloc_mem(unsigned int &len);
			virtual int free_mem(char*, unsigned int len);
		private:
			int tryclear_poolcache();

			std::vector<char*> mvpools[10];
			int mvallocnum[10];
			int mvallocmax[10];
			time_t mprecleartime;

			int calculate_index(unsigned int size);
			int poolcachesize;
			int mmaxcachesize;
		};
	}
}

#endif
